package com.atwisdom.star.service.equipment.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.atwisdom.star.common.util.UuidTool;
import com.atwisdom.star.common.vo.JsonResult;
import com.atwisdom.star.common.vo.ResultInfo;
import com.atwisdom.star.core.bsl.modelClass.resource.Impl.ResourceInstanceBslServiceImpl;
import com.atwisdom.star.core.dsl.modelClass.resource.Impl.ResourceInstanceDslServiceImpl;
import com.atwisdom.star.exception.pojo.BusinessException;
import com.atwisdom.star.service.equipment.OverLimitReportService;
import com.atwisdom.star.service.util.ResourceUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @ClassName: OverLimitReportServiceImpl
 * @ Description:
 * @author: wjj
 * @Date 2024/7/26
 */
@Service
public class OverLimitReportServiceImpl implements OverLimitReportService {

    @Autowired
    ResourceInstanceBslServiceImpl resourceInstanceBslServiceImpl;

    @Autowired
    private ResourceInstanceDslServiceImpl resourceInstanceDslServiceImpl;

    @Autowired
    ResourceUtil resourceUtil;

    private final String TYPE = "resource";
    private final String TechClassName = "TechOverLimit";
    private final String LabClassName = "LabOverLimit";


    /**
     * 品规维度报表统计
     *
     * @return 每种品规工艺及实验室报警数
     * @throws BusinessException
     */
    @Override
    @Transactional
    public ResultInfo<?> statisticsByProduct() throws BusinessException {
        String techCond = "isOverLimit=='是'&&className=='" + TechClassName + "'&&type=='" + TYPE + "'";
        List<JSONObject> techList = resourceInstanceDslServiceImpl.query(techCond, TechClassName, null);

        String labCond = "isOverLimit=='是'&&className=='" + LabClassName + "'&&type=='" + TYPE + "'";
        List<JSONObject> labList = resourceInstanceDslServiceImpl.query(labCond, LabClassName, null);

        JSONObject data = new JSONObject();
        JSONArray product = new JSONArray();
        JSONArray lab = new JSONArray();

        JSONObject values = new JSONObject();
        JSONArray tech = new JSONArray();

        Map<String, Long> statisticsMap = techList.stream()
                .collect(Collectors.groupingBy(tmp -> tmp.getJSONObject("values").getString("productName"), Collectors.counting()));
        Map<String, Long> labMap = labList.stream()
                .collect(Collectors.groupingBy(tmp -> tmp.getJSONObject("values").getString("productName"), Collectors.counting()));

        statisticsMap.forEach((k, v) -> {
            product.add(k);
            tech.add(v);
            if (labMap.get(k) != null) {
                lab.add(labMap.get(k));
            } else {
                lab.add(0);
            }
        });
        values.put("tech", tech);
        values.put("lab", lab);
        data.put("product", product);
        data.put("values", values);

        return JsonResult.success(data);
    }

    /**
     * 设备维度报表统计
     *
     * @return 每种设备工艺及实验室报警数
     * @throws BusinessException
     */
    @Override
    @Transactional
    public ResultInfo<?> statisticsByEquip() throws BusinessException {
        String techCond = "isOverLimit=='是'&&className=='" + TechClassName + "'&&type=='" + TYPE + "'";
        List<JSONObject> techList = resourceInstanceDslServiceImpl.query(techCond, TechClassName, null);

        String labCond = "isOverLimit=='是'&&className=='" + LabClassName + "'&&type=='" + TYPE + "'";
        List<JSONObject> labList = resourceInstanceDslServiceImpl.query(labCond, LabClassName, null);

        JSONObject data = new JSONObject();
        JSONArray equip = new JSONArray();
        JSONArray lab = new JSONArray();

        JSONObject values = new JSONObject();
        JSONArray tech = new JSONArray();

        Map<String, Long> statisticsMap = techList.stream()
                .collect(Collectors.groupingBy(tmp -> tmp.getJSONObject("values").getString("equipName"), Collectors.counting()));
        Map<String, Long> labMap = labList.stream()
                .collect(Collectors.groupingBy(tmp -> tmp.getJSONObject("values").getString("equipName"), Collectors.counting()));

        statisticsMap.forEach((k, v) -> {
            equip.add(k);
            tech.add(v);
            if (labMap.get(k) != null) {
                lab.add(labMap.get(k));
            } else {
                lab.add(0);
            }
        });
        values.put("tech", tech);
        values.put("lab", lab);
        data.put("equip", equip);
        data.put("values", values);

        return JsonResult.success(data);
    }

    /**
     * 增加工艺超限测试数据-仅限测试
     */
    @Override
    @Transactional
    public ResultInfo<?> testTechAdd(JSONObject data) {
        JSONObject values = testData(data);
        JSONObject addJson = this.resourceInstanceDslServiceImpl.add(TYPE, TechClassName, UuidTool.getUUID32(), values);
        return JsonResult.success(addJson);
    }

    /**
     * 增加实验室超限测试数据-仅限测试
     */
    @Override
    @Transactional
    public ResultInfo<?> testLabAdd(JSONObject data) {
        JSONObject values = testData(data);
        JSONObject addJson = this.resourceInstanceDslServiceImpl.add(TYPE, LabClassName, UuidTool.getUUID32(), values);
        return JsonResult.success(addJson);
    }

    private JSONObject testData(JSONObject data) {
        JSONObject values = new JSONObject();
        values.put("productId", data.getLong("productId"));
        values.put("productName", data.getString("productName"));
        values.put("equipId", data.getLong("equipId"));
        values.put("equipName", data.getString("equipName"));
        values.put("paramId", data.getLong("paramId"));
        values.put("paramName", data.getString("paramName"));
        values.put("unit", data.getString("unit"));
        values.put("maxParam", data.getDouble("maxParam"));
        values.put("minParam", data.getDouble("minParam"));
        values.put("actual", data.getDouble("actual"));
        values.put("collectionTime", data.getString("collectionTime"));
        values.put("isOverLimit", data.getString("isOverLimit"));
        return values;
    }
}